package com.smartx.app.util.libimage;

import android.content.ContentResolver;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.util.Base64;
import android.widget.ImageView;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class BitmapUtil {

	/**
	 * 计算图片的缩放值 如果图片的原始高度或者宽度大与我们期望的宽度和高度，我们需要计算出缩放比例的数值。否则就不缩放。
	 * heightRatio是图片原始高度与压缩后高度的倍数， widthRatio是图片原始宽度与压缩后宽度的倍数。
	 * inSampleSize就是缩放值 ，取heightRatio与widthRatio中最小的值。
	 * inSampleSize为1表示宽度和高度不缩放，为2表示压缩后的宽度与高度为原来的1/2(图片为原1/4)。
	 * 
	 * @param options
	 * @param reqWidth
	 * @param reqHeight
	 * @return
	 */
	public static int calculateInSampleSize(BitmapFactory.Options options,
			int reqWidth, int reqHeight) {
		// Raw height and width of image
		final int height = options.outHeight;
		final int width = options.outWidth;
		int inSampleSize = 1;

		if (height > reqHeight || width > reqWidth) {

			// Calculate ratios of height and width to requested height and
			// width
			final int heightRatio = Math.round((float) height
					/ (float) reqHeight);
			final int widthRatio = Math.round((float) width / (float) reqWidth);

			// Choose the smallest ratio as inSampleSize value, this will
			// guarantee
			// a final image with both dimensions(尺寸) larger than or equal to
			// the requested height and width.
			inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
		}
		return inSampleSize;
	}


	public static Bitmap getBitmap(ContentResolver cr, Uri uri, int maxWidth) {
		InputStream input1 = null;
		InputStream input2 = null;
		try {
			input1 = cr.openInputStream(uri);
			input2 = cr.openInputStream(uri);
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inJustDecodeBounds = true;
			BitmapFactory.decodeStream(input1, null, options);
			int inSampleSize = calculateInSampleSize(options, maxWidth,
					maxWidth);
			options.inSampleSize = inSampleSize;
			options.inJustDecodeBounds = false;
			Bitmap bitmap = BitmapFactory.decodeStream(input2, null, options);
			return bitmap;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (input1 != null) {
				try {
					input1.close();
				} catch (IOException e) {

					// TODO Auto-generated catch block
					e.printStackTrace();

				}
			}
			if (input2 != null) {
				try {
					input2.close();
				} catch (IOException e) {

					// TODO Auto-generated catch block
					e.printStackTrace();

				}
			}
		}
		return null;
	}

	/**
	 * 根据路径获得图片并压缩返回bitmap用于显示
	 * 
	 * @return
	 */
	public static Bitmap getSmallBitmap(String filePath, int w, int h) {
		final BitmapFactory.Options options = new BitmapFactory.Options();

		// 该值设为true那么将不返回实际的bitmap不给其分配内存空间而里面只包括一些解码边界信息即图片大小信息
		options.inJustDecodeBounds = true;// inJustDecodeBounds设置为true，可以不把图片读到内存中,但依然可以计算出图片的大小
		BitmapFactory.decodeFile(filePath, options);

		// Calculate inSampleSize
		options.inSampleSize = calculateInSampleSize(options, w, h);

		// Decode bitmap with inSampleSize set
		options.inJustDecodeBounds = false;// 重新读入图片，注意这次要把options.inJustDecodeBounds
											// 设为 false
		Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);// BitmapFactory.decodeFile()按指定大小取得图片缩略图
		return bitmap;
	}


	/**
	 * 根据图片ID获得ImageView对象
	 *
	 * @param drawableRes
	 * @return
	 */
//	public static void makeView(ImageView iv, int drawableRes,Context Context) {
//		Bitmap Bitmap = LibTools.readBitMap(Context, drawableRes);
//		iv.setImageBitmap(Bitmap);
//	}

	/**
	 * 临时这么写
	 * TODO: 统一图片压缩算法
	 */
	public static Bitmap stringtoBitmap(String base64Str){
		//将字符串转换成Bitmap类型
		Bitmap bitmap=null;
		try {
			byte[]bitmapArray;
			bitmapArray= Base64.decode(base64Str, Base64.DEFAULT);
			BitmapFactory.Options newOpts = new BitmapFactory.Options();
			//开始读入图片，此时把options.inJustDecodeBounds 设回true了
			newOpts.inJustDecodeBounds = true;
			//设置为true就可以让解析方法禁止为bitmap分配内存，返回值也不再是一个Bitmap对象，而是null
			BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.length,newOpts);
			int w = newOpts.outWidth;
			int h = newOpts.outHeight;
			//现在主流手机比较多是800*480分辨率，所以高和宽我们设置为
			float hh = 480f;//这里设置显示图片高度480f
			float ww = 480f;//这里设置宽度为480f
			//缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
			int be = 1;//be=1表示不缩放
			if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
				be = (int) (newOpts.outWidth / ww);
			} else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
				be = (int) (newOpts.outHeight / hh);
			}
			if (be <= 0)
				be = 1;
			newOpts.inSampleSize = be;//设置缩放比例
			newOpts.inPreferredConfig = Bitmap.Config.RGB_565;
			newOpts.inJustDecodeBounds = false;
			//重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
			bitmap=BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.length,newOpts);
			return compress480Image(bitmap);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 质量压缩
	 * @param image
	 * @return
	 */
	private static Bitmap compress480Image(Bitmap image) throws IOException {
		if (image==null) {
			return null;
		}
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
		int options = 100;
		while ( baos.toByteArray().length / 1024>100) {  //循环判断如果压缩后图片是否大于100kb,大于继续压缩
			baos.reset();//重置baos即清空baos
			options -= 10;//每次都减少10
			image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%，把压缩后的数据存放到baos中

		}
		ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
		Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
		isBm.close();
		baos.close();
		return bitmap;
	}


}
